package com.sherlockHolmes.init.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sherlockHolmes.init.base.template.MessageTemplate;
import com.sherlockHolmes.init.base.utils.DateUtil;
import com.sherlockHolmes.init.entity.dao.*;
import com.sherlockHolmes.init.entity.dto.ApproveCommunityDTO;
import com.sherlockHolmes.init.entity.dto.AssetDTO;
import com.sherlockHolmes.init.service.*;
import com.sherlockHolmes.init.mapper.CommunityMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 四月一日 君寻
* &#064;description  针对表【community(圈子表)】的数据库操作Service实现
* &#064;createDate  2024-03-27 11:48:55
 */
@Service
public class CommunityServiceImpl extends ServiceImpl<CommunityMapper, Community>
    implements CommunityService, SearchService {
    @Resource
    private CommunityMapper communityMapper;
    @Resource
    private UserInfoServiceImpl userInfoService;
    @Resource
    private ApplicationService applicationService;
    @Resource
    private ApplyConditionService applyConditionService;
    @Resource
    private CircleMemberService circleMemberService;
    @Resource
    private MessageService messageService;

    /**
     * 创建圈子
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int addCommunity(Community community, HttpServletRequest request) {
        //检查当前用户是否是vip vip创建圈子无需等级校验 可以创建三个圈子 ，非vip只能创建一个圈子 且等级要大于等于2级
        //一共六级
        //检查当前用户等级是否满足创建圈子条件
        UserInfo userInfo = userInfoService.getUserInfo(request);
        if(userInfo.getUsable()==1){//账号被封禁
            throw new RuntimeException("您的账号被封禁了,无法创建圈子,详细原因请查看消息");
        }
        Long count = new LambdaQueryChainWrapper<>(communityMapper)
                .eq(Community::getCreateUserId, userInfo.getId())
                .eq(Community::getValid, 0)
                .count();
        if(userInfo.getVip()==0){//vip用户
            if(count>=3){//已经创建了3个圈子
                throw new RuntimeException("您已经创建了3个圈子,无法继续创建");
            }
        }else {
            if(userInfo.getLevel()<2){//等级不够
                throw new RuntimeException("您的等级不够,无法创建圈子,请升级后再试");
            }
            if(count>=1){
                throw new RuntimeException("您已经创建了1个圈子,无法继续创建");
            }
        }
        communityMapper.insert(community);
        List<Community> list = lambdaQuery().eq(Community::getCreateUserId, userInfo.getId())
                .eq(Community::getValid, 0)
                .list();
        if(ObjectUtil.isNotEmpty(list)&&list.size()>0){
            //TODO 根据communityId查询出circleMember

        }
        return 1;
    }
    /**
     * 申请加入圈子
     */
    @Override
    public int applyCommunity(Integer communityId, HttpServletRequest request) {
        Community community = communityMapper.selectById(communityId);
        UserInfo userInfo = userInfoService.getUserInfo(request);
        Integer conditionId = community.getConditionId();
        if(conditionId==null){//圈子没有申请条件，直接添加一条申请记录
            Application application = new Application();
            application.setCommunityId(communityId);
            application.setCreateTime(new Date());
            application.setUserId(userInfo.getId());
            applicationService.save(application);
        }else {
            if(check(conditionId,userInfo)){//检查当前用户是否满足申请条件
                Application application = new Application();
                application.setCommunityId(communityId);
                application.setCreateTime(new Date());
                application.setUserId(userInfo.getId());
                applicationService.save(application);
            }
        }
        return 1;
    }
    /**
     * 审批加入圈子
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int approveCommunity(ApproveCommunityDTO approveCommunityDTO, HttpServletRequest request) {
        UserInfo userInfo = userInfoService.getUserInfo(request);//获取用户
        Integer id = approveCommunityDTO.getId();//申请记录id
        Integer userId = approveCommunityDTO.getUserId();//用户id
        Integer communityId = approveCommunityDTO.getCommunityId();//圈子id
        Community community = communityMapper.selectById(communityId);//获取圈子申请条件
        ApplyCondition applyCondition = applyConditionService.selectById(community.getConditionId());
        Integer applicationResult = approveCommunityDTO.getApplicationResult();//申请结果
            Application application = new Application();
            application.setUpdateTime(new Date());
            application.setApplicationResult(applicationResult);
            application.setId(id);
            applicationService.updateById(application);
            if(applicationResult==1){//同意申请
                //添加圈子成员
                CircleMember circleMember = new CircleMember();
                circleMember.setCommunityId(communityId);
                circleMember.setUserId(userId);
                circleMember.setCreateTime(new Date());
                circleMemberService.save(circleMember);
                //发一条消息告知对方申请被同意
                messageService.sendMessage(userInfo.getId(),userId,"0",String.format(MessageTemplate.APPLY_COMMUNITY,community.getTitle()));
            } else if (applicationResult==2) {//拒绝申请
                //发一条消息告知对方申请被拒绝
                messageService.sendMessage(userInfo.getId(),userId,"0",String.format(MessageTemplate.REJECT_COMMUNITY,community.getTitle()));
                applicationService.refunds(userInfo, Collections.singletonList(userId),applyCondition);//退回费用
            }
        return 1;
    }
    /**
     * 解散圈子
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int dissolveTheCommunity(Integer communityId, HttpServletRequest request) {
        UserInfo userInfo = userInfoService.getUserInfo(request);//检查当前用户时是否是创建人
        Community community = communityMapper.selectById(communityId);
        ApplyCondition applyCondition = applyConditionService.selectById(community.getConditionId());
        List<Integer> userList=new ArrayList<>();
        if(userInfo.getId().equals(community.getCreateUserId())){//是创建人
            //查找当前是否有未审批的申请记录
           List<Application> list = applicationService.unApplication(communityId,0);
           if(list.size()>0){//有未审批的申请记录,对未审批的记录全部拒绝,并通知申请人圈子已解散
              //检查圈子申请条件，需要付费的退回费用
               if(ObjectUtil.isNotEmpty(community.getConditionId())){
                   switch (applyCondition.getType())
                       {
                           case "2"://需要付硬币
                           case "3"://需要付金币
                               userList.addAll(list.stream().map(Application::getUserId).collect(Collectors.toList()));
                       }
               }
               userList.forEach(userId -> {
                   ApproveCommunityDTO approveCommunityDTO = new ApproveCommunityDTO();
                   approveCommunityDTO.setCommunityId(communityId);
                   approveCommunityDTO.setUserId(userId);
                   approveCommunityDTO.setApplicationResult(2);
                   approveCommunity(approveCommunityDTO,request);
               });
           }
            //查找圈子成员，不满七天的退回费用
            List<CircleMember> memberList = circleMemberService.list(new QueryWrapper<CircleMember>()
                    .eq("community_id", communityId)
                    .between("create_time", DateUtil.offsetDay(DateUtil.getNowTime(),-7),DateUtil.getNowTime())
            );
            if(ObjectUtil.isNotEmpty(memberList)&&memberList.size()>0){
                List<Integer> collect = memberList.stream()
                        .map(CircleMember::getUserId)
                        .filter(userId ->!userId.equals(community.getCreateUserId()))
                        .collect(Collectors.toList());
                //退费
                applicationService.refunds(userInfo, collect,applyCondition);//退回费用
            }
            //删除圈子成员
            //删除圈子
            circleMemberService.lambdaUpdate().eq(CircleMember::getCommunityId,communityId).remove();
            communityMapper.deleteById(communityId);//删除圈子
            return 1;//圈子解散
        }
        return 0;//不是创建人
    }

    /**
     * 检查当前用户是否满足申请条件
     */
    public boolean check(Integer conditionId,UserInfo userInfo){
        ApplyCondition applyCondition = applyConditionService.selectById(conditionId);
        if("1".equals(applyCondition.getType())){
            if(userInfo.getLevel()<applyCondition.getNum()){
                throw new RuntimeException("您的等级不够,无法申请该圈子,请升级后再试");
            }
        } else if ("2".equals(applyCondition.getType())) {//硬币
            if (userInfo.getCoin().compareTo(BigDecimal.valueOf(applyCondition.getNum()))<0){
                throw new RuntimeException("您的硬币不够,无法申请该圈子,请充值后再试");
            }else {
                userInfoService.reduceAsset(new AssetDTO("2",userInfo.getId(),applyCondition.getNum()));//扣除相应的硬币
            }
        }else if ("3".equals(applyCondition.getType())) {//金币
            if (userInfo.getGold().compareTo(BigDecimal.valueOf(applyCondition.getNum()))<0){
                throw new RuntimeException("您的金币不够,无法申请该圈子,请充值后再试");
            }else {
                userInfoService.reduceAsset(new AssetDTO("1",userInfo.getId(),applyCondition.getNum()));//扣除相应的金币
            }
        }
        return true;
    }
}




